from sqlalchemy.orm import Session
from sqlalchemy import select, text, update, insert, delete
from typing import Optional, Dict, List
from app.api.schemas.user import User_Schema, User_Update_Schema
from app.db.model.user import sysUser_DB
from passlib.context import CryptContext
from sqlalchemy.exc import IntegrityError
import uuid

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# 注册新用户，返回成功信息
def register_user(db: Session, user: User_Schema) -> Dict:
    """
    注册新用户的函数
    :param db: 数据库会话对象，用于与数据库交互。
    :param user: 包含用户信息的 User_Schema 对象。
    :return: 一个字典，包含注册成功的消息。
    """
    # user.passWord = get_password_hash(user.passWord)
    try:
        stmt = (insert(sysUser_DB).values(user.model_dump()))
        db.execute(stmt)
        # 提交事务以保存新用户到数据库
        db.commit()
        # 刷新会话以获取新用户的ID
        return "新用户注册成功"
    except IntegrityError:
        # 如果发生完整性错误（例如，用户名已存在），回滚事务并返回错误消息
        db.rollback()
        return "注册失败，用户名已存在"
    except Exception as e:
        # 如果发生其他异常，回滚事务并返回错误消息
        db.rollback()
        return f"注册失败，发生错误: {str(e)}"

# 通过用户名查询用户，返回用户信息(密码不返回)
def get_user(db: Session, login_name: str) -> List:
    """
    根据用户名查询用户
    :param db: 数据库session
    :param login_name: 查询用户名
    :return: 查询到的用户
    """
    try:
        # 如果没有提供用户名，则查询所有用户的id、用户名和姓名
        if login_name is None:
            res = db.execute(select(sysUser_DB.user_id, sysUser_DB.login_name, sysUser_DB.user_name, sysUser_DB.phonenumber,
                sysUser_DB.status, sysUser_DB.user_role, sysUser_DB.remark, sysUser_DB.create_by, sysUser_DB.update_by).where(sysUser_DB.del_flag == '0'))
            # return await db.execute(select(sysUser_DB.user_id, sysUser_DB.login_name, sysUser_DB.user_name)).mappings().all()  # mappings方法将查询返回的元组转换为列表
            return res.mappings().all()  # mappings方法将查询返回的元组转换为列表
        # 如果提供了用户名，则查询该用户名对应的用户对象
        else:
            return db.execute(select(sysUser_DB).where(sysUser_DB.login_name == login_name).where(sysUser_DB.del_flag == '0')).scalars().first()
    except Exception as e:
        # 处理异常，例如记录日志或返回错误信息
        print(f"Error fetching user: {e}")
        return []

# 通过用户名更新用户
def update_userinfo(db: Session, user: User_Update_Schema):
    """
    更新用户信息的函数
    :param db: 数据库会话对象，用于与数据库交互。
    :param user: 包含用户信息的 User_Schema 对象。
    :return: 一个字符串，表示用户更新成功的消息。
    """
    try:
        # 使用SQLAlchemy的update函数构建更新语句，更新sysUser_DB表中指定用户名的用户记录
        stmt = (update(sysUser_DB).where(sysUser_DB.login_name == user.login_name).values(user.model_dump()))
        # 执行更新语句
        db.execute(stmt)
        # 提交数据库会话，将更新保存到数据库中
        db.commit()
        # 返回更新后的用户对象
        return user
    except Exception as e:
        # 如果发生异常，回滚事务并返回错误消息
        print(f"Error updating user: {str(e)}")
        

def del_user(db: Session, login_name: str) -> Dict:
    """
    根据用户名删除用户的函数
    :param db: 数据库会话对象，用于与数据库交互。
    :param login_name: 要删除的用户的用户名。
    :return: 一个字典，包含删除成功或失败的消息。
    """
    try:
        # 使用SQLAlchemy的delete函数构建删除语句，删除sysUser_DB表中指定用户名的用户记录
        # stmt = (delete(sysUser_DB).where(sysUser_DB.login_name == login_name))
        stmt = (update(sysUser_DB).where(sysUser_DB.login_name == login_name).values(del_flag='1'))  # 逻辑删除
        # 执行删除语句
        db.execute(stmt)
        # 提交数据库会话，将删除操作保存到数据库中
        db.commit()
        # 返回删除成功的消息
        return f"用户名为{login_name}的账号删除成功"
    except Exception as e:
        # 如果发生异常，回滚事务并返回错误消息
        db.rollback()
        print(f"Error deleting user: {e}")
        return f"用户名为{login_name}的账号删除失败"

# 校验用户
def check_user(login_user, db: Session):
    """
    校验用户
    :param login_user: 登录用户，schemas为class User
    :return: user
    """
    # 查询用户
    user = get_user(db, login_user['login_name'])
    # 判断是否存在用户，未查询到则返回
    if not user:
        return {"user":None, "message": "用户不存在"}
    # 判断用户状态是否为禁用，为禁用则返回
    if user.status == '0':
        return {"user":None, "message": "用户已被禁用"}
    # 判断密码是否正确，不正确则返回，正确返回用户名
    if verify_password(login_user['password'], user.password):
        return {"user":user, "message": "验证成功"}
    else:
        return {"user":None, "message": "密码错误"}

# 获得hash密码
def get_password_hash(password):
    """
    哈希来自用户的密码
    :param password: 原密码
    :return: 哈希后的密码
    """
    return pwd_context.hash(password)

# 校验密码
def verify_password(plain_password, hashed_password):
    """
    校验接收的密码是否与存储的哈希值匹配
    :param plain_password: 原密码
    :param hashed_password: 哈希后的密码
    :return: 返回值为bool类型，校验成功返回True,反之False
    """
    # 前端
    # return pwd_context.verify(plain_password, hashed_password) 
    if plain_password == hashed_password:
        return True
    else:
        return False